package com.ddf.controller;

import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.ddf.entity.User;

@Controller
@RequestMapping("/ModelAttributesDemo")
public class ModelAttributesDemo {
	
	private static final String SUCCESS = "success";
	
	/**
	 * SpringMVC確定POJO入參的流程
	 * 1. 确定一个key
	 * 	a. 如果目标方法没有用@ModelAndAttributes修饰，则Key为POJO类名首字母小写
	 *  b. 若使用了@ModelAndAttributes修饰，则Key为注解的value属性值
	 * 2. 在SpringMVC封装的存参的implictModel中查找key对应的对象，若存在，则作为参数入参。
	 *  a. 若为1中的b情况，则能够找到。
	 *  b. 如果找不到，则检查当前的handler是否使用了@SessionAttributes注解，如果使用了该注解，
	 *     且在注解的value属性中包含着入参的Key,则会从HttpSession中获取对应的value来入参，如果
	 *     value存在，但没有数据，则抛出异常
	 * 3. 若当前handler没有使用@SessionAttrbutes注解或者当前使用的@SessionAttributes注解
	 *    不包含入参对应的key,则利用反射，新建一个POJO类来入参。
	 * 4. SpringMVC会把key和value保存到implictModel中，进而保存到request域中。
	 *  
	 *
	 */
	
	/**
	 * 此注解会在同类中的所有方法执行前都执行
	 * @ModelAttributes注解的作用
	 *  也可以用来修饰入参的key,其value值会在implictModel中通过key查找对象来入参，
	 *  之后会把入参后的POJO对象（可能修改）重新存入implictModel中
	 * @param id
	 * @param map
	 */
	@ModelAttribute
	public void getUser(@RequestParam Integer id, Map<String, User> map) {
		if(id != null) {
			// 模拟从数据中取出数据的样本
			User user = new User(1, "dingdongfang", "123456", "nan", "1041765757@qq.com");
			map.put("user", user);
		}
	}
	
	/**
	 * 使用场景： 对数据库中存在的对象进行修改，有一些值是固定值，页面不会传入，也不允许修改，
	 * 如果不传入，直接对对象进行更新，则会对未传入的字段更新为空，所以使用ModelAttributes
	 * 注解让SpringMVC自动实现将页面传入的参数覆盖数据库中的相同字段的属性值，这样未传入的
	 * 则保持与数据库中一致
	 * @param user
	 * @param map
	 * @return
	 */
	@RequestMapping("/testModelAttributes")
	public String updateUser(User user, Map<String, User> map) {
		map.put("user", user);
		return SUCCESS;
	}
}
